package com.hnchances.studentscoresystem.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * Web 配置类
 * 功能：1. 处理跨域请求（支持前端调用后端接口）
 *      2. 配置 JSON 消息转换器（解决 LocalDateTime 日期格式序列化问题）
 *      3. 适配文档中接口的 POST 方式与 JSON 数据格式需求
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    /**
     * 跨域配置
     * 允许前端（如 Vue/React）通过 AJAX 调用后端接口，解决浏览器跨域限制
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 对所有接口生效
                .allowedOrigins("*") // 允许所有前端域名（生产环境可指定具体域名，如 "http://localhost:8081"）
                .allowedMethods("POST", "GET", "PUT", "DELETE") // 允许文档中涉及的请求方法（核心为 POST）
                .allowedHeaders("*") // 允许所有请求头（如 Authorization、Content-Type）
                .exposedHeaders("*") // 允许前端获取所有响应头
                .maxAge(3600L); // 预检请求缓存时间（1小时，减少重复预检请求）
    }

    /**
     * 配置 JSON 消息转换器
     * 解决：1. LocalDateTime 等 JDK8 日期类型的 JSON 序列化格式问题
     *      2. 确保请求/响应的 JSON 数据与实体类字段正确映射（如驼峰命名匹配）
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        WebMvcConfigurer.super.configureMessageConverters(converters);

        // 1. 创建 Jackson 消息转换器
        MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = new ObjectMapper();

        // 2. 注册 JDK8 日期时间模块，解决 LocalDateTime 序列化问题
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        // 配置 LocalDateTime 序列化格式（与数据库 datetime 类型格式对齐，如 "2024-05-20 14:30:00"）
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter));

        // 3. 注册参数名称模块，支持构造函数参数名解析（提升 JSON 反序列化兼容性）
        objectMapper.registerModule(new ParameterNamesModule())
                .registerModule(javaTimeModule);

        // 4. 设置转换器的 ObjectMapper，并添加到转换器列表
        jacksonConverter.setObjectMapper(objectMapper);
        converters.add(jacksonConverter);
    }

    /**
     * 自定义 ObjectMapper Bean（全局生效）
     * 确保所有 JSON 处理（如接口请求/响应、MyBatis 结果映射）使用统一的配置
     */
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter));

        objectMapper.registerModule(new ParameterNamesModule())
                .registerModule(javaTimeModule);
        return objectMapper;
    }
}